package com.njmd.framework.utils.web;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.math.NumberUtils;
import org.apache.log4j.Logger;

import com.njmd.mdbs.web.constants.RequestNameConstants;
import com.njmd.mdbs.web.constants.SessionNameConstants;
import com.njmd.mdbs.web.entity.sys.SysConfig;
import com.njmd.mdbs.web.security.LoginToken;

public class WebContextHolder {
	private static Logger logger = Logger.getLogger(WebContextHolder.class);

	private static ThreadLocal<HttpServletRequest> requestHolder = new ThreadLocal<HttpServletRequest>();

	public static void setRequest(HttpServletRequest request) {
		requestHolder.set(request);
	}

	public static HttpServletRequest getRequest() {
		return requestHolder.get();
	}

	/**
	 * 获得当前登录用户会话
	 * 
	 * @return
	 */
	public static LoginToken getCurrLoginToken() {

		HttpServletRequest request = requestHolder.get();
		if (request != null)
			return (LoginToken) SessionUtils.getObjectAttribute(request,
					SessionNameConstants.LOGIN_TOKEN);
		else {
			// System.out.println("getCurrLoginToken 为 NULL 啊");
			return null;
		}
	}

	/**
	 * 向request中保存当前正在操作的实体，主要由日志记录拦截器使用
	 * @param entity
	 */
	public static void savedObjectForLog(Object entity) {
		HttpServletRequest request = requestHolder.get();
		if (null != request) {
			request.setAttribute(RequestNameConstants.SAVED_OBJECT, entity);
		}
	}

	/**
	 * 从request中获取当前正在操作的实体，主要由日志记录拦截器使用
	 * @param entity
	 */
	public static Object getSavedObject() {
		HttpServletRequest request = requestHolder.get();
		if (null != request) {
			return request.getAttribute(RequestNameConstants.SAVED_OBJECT);
		} else
			return null;
	}

	/**
	 * 验证当前系统中使用的授权信息是否失效。
	 * @param request
	 * @return
	 * 
	 * Edit by 孙强伟  at 20130723 
	 */
	public static String checkLicenseValid(HttpServletRequest request) {
		String msg = "";
		if (null != request) {
			String isLicenseOK = (String) request.getSession()
					.getServletContext()
					.getAttribute(SysConfig.IS_LICENSE_OK);
			
			Boolean isExpiry = (Boolean) request.getSession()
					.getServletContext().getAttribute(SysConfig.IS_EXPIRY);
			
			if (null == isLicenseOK || isLicenseOK.equals("0_false")
				|| (isLicenseOK.equals("0_true") && isExpiry)) {
				msg = "对不起，系统试用期已到！";
			} else if (isLicenseOK.equals("1_false")) {
				msg = "对不起，License失效，请联系系统管理员！";
			}
		}
		return msg;
	}

	/**
	 * IP地址访问控制
	 * 1、当在web服务器上通过127.0.0.1来访问网站时，不进行访问控制。
	 * 2、如果不是通过127.0.0.1访问网站时，则根据授权版本中的授权IP数进行访问过滤。
	 * 	a、当License.ips的值为*号，则表示没有授权IP个数限制，此时就先进行黑名单过滤再进行白名单过滤。
	 * 	b、当License.ips的值为数据时，则表示有授权IP个数限制，默认会阻止全部IP地址的访问，
	 * 		除了白名单列表中的IP地址。
	 *  c、工作站管理中的IP地址也是在放行之后。
	 * @param request
	 * @return
	 * 
	 * Edit by 孙强伟  at 20130723
	 */
	public static boolean checkIpValid(HttpServletRequest request) {
		boolean result = false;
		if (null != request) {
			String remoteIp = RequestUtils.getIpAddr(request);
			if("127.0.0.1".equals(remoteIp))
				return true;
			String licenseIps = (String) request.getSession()
					.getServletContext().getAttribute(SysConfig.LICENSE_IPS);
			
			String[] allowIps=(String[]) request.getSession()
					.getServletContext().getAttribute(SysConfig.ALLOW_IPS);
			
			String[] denyIps=(String[]) request.getSession()
					.getServletContext().getAttribute(SysConfig.DENY_IPS);
			
			String[] wsIps=(String[])request.getSession()
					.getServletContext().getAttribute(SysConfig.WORKSTATION_IPS);
			
			//c
			if(null!=wsIps && wsIps.length>0){
				if(hasMatch(remoteIp, wsIps, Integer.MAX_VALUE)){
					return true;
				}
			}
			
			if (null != licenseIps) {
				//a
				if ("*".equals(licenseIps)) {
					int ips = Integer.MAX_VALUE;
					if(hasMatch(remoteIp, allowIps, ips)){
						return true;
					}
					if(hasMatch(remoteIp,denyIps,ips)){
						return false;
					}
					
					return true;
				//b
				} else if (NumberUtils.isNumber(licenseIps)) {
					int ips = Integer.valueOf(licenseIps);
//					if(hasMatch(remoteIp,denyIps,ips)){
//						return false;
//					}
					
					if(hasMatch(remoteIp, allowIps, ips)){
						return true;
					}
				}
			}
		}

		return result;
	}

	private static boolean hasMatch(String clientAddr, String[] regExps,int nums){
		int endIndex=regExps.length>nums?nums:regExps.length;
		for (int i = 0; i < endIndex; i++){
			if (clientAddr.matches(regExps[i]))
				return true;
		}
		return false;
	}

}
